Злой профессор
только что задал Вам следующую задачу. Определим последовательность следующим
образом:
x0 = 1,
xi = +
+
Для каждого значения i вычислите xi.
Вход. Состоит из нескольких строк, каждая из которых содержит
одно целое число i (0 ≤ i ≤ 106). Последняя строка содержит -1 и не
обрабатывается.
Выход. Для каждого
значения i (кроме последнего -1) выведите
соответствующее значение xi, вычисленное по модулю 106.
Пример
входа |
Пример
выхода |
0 1 2 10 -1 |
1 3 5 21 |
рекуррентное
соотношение
Анализ алгоритма
Значение xi будем вычислять при помощи
функции f(i). Для этого следует реализовать
рекуррентность
=
+
+
,
с запоминанием значений f(i) в линейном массиве dp размером 106.
Реализация алгоритма
Значения xi будем хранить в массиве dp.
#define MAX 1000001
int dp[MAX];
Функция f(n) вычисляет значение xn.
int f(int n)
{
Условие окончания рекурсии.
if (n ==
0) return 1;
Если значение xn уже вычислено (dp[n] ≠ -1),
возвращаем его.
if (dp[n] != -1) return dp[n];
Вычисляем рекурсивно первое, второе и
третье слагаемое.
int a = f((int)(n
- sqrt(n)));
int b = f((int)(log(n)));
int c = f((int)(n * sin(n) * sin(n)));
Вычисляем, запоминаем и возвращаем
значение xn.
return dp[n] = (a + b +
c) % 1000000;
}
Основная часть программы. Пусть dp[i] = -1, если значение xi еще не вычислено.
memset(dp,-1,sizeof(dp));
Обрабатываем несколько тестов. Для каждого значения n выводим ответ.
while(scanf("%d",&n),
n != -1)
printf("%d\n",f(n));
Реализация алгоритма – не рекурсивная
Значения xi будем хранить в массиве x.
int x[1000001];
Заполняем элементы массива x согласно заданной рекуррентности.
x[0] = 1;
for (i = 1; i <= 1000000; i++)
x[i]
= (x[(int)(i - sqrt(i))] + x[(int)(log(i))]
+
x[(int)(i *
sin(i) * sin(i))]) % 1000000;
Обрабатываем несколько тестов. Для каждого значения n выводим ответ.
while (scanf("%d",
&n), n != -1)
printf("%d\n",
x[n]);
Java реализация
import java.util.*;
public class Main
{
static int dp[] = new int[1000001];
static int f(int n)
{
if (n ==
0) return 1;
if (dp[n] !=
-1) return dp[n];
int a = f((int)(n -
Math.sqrt(n)));
int b = f((int)(Math.log(n)));
int c = f((int)(n *
Math.sin(n) * Math.sin(n)));
return dp[n] = (a + b + c) %
1000000;
}
public static void
main(String[] args)
{
Scanner con = new
Scanner(System.in);
Arrays.fill(dp,
-1);
while(true)
{
int n = con.nextInt();
if (n ==
-1) break;
System.out.println(f(n));
}
con.close();
}
}
Python реализация
import math
Инициализируем массив x.
x = [0] * 1000001
x[0] = 1
Заполняем элементы массива x согласно заданной рекуррентности.
for i in range(1, 1000001):
x[i] = (x[int(i - math.sqrt(i))] +
x[int(math.log(i))] +
x[int(i * math.sin(i)**2)]) % 1000000
Обрабатываем несколько тестов. Для каждого значения n выводим ответ.
while True:
n = int(input())
if n == -1:
break
print(x[n])